import lightgbm as lgb  # 添加LightGBM导入
import pandas as pd
from sklearn.metrics import accuracy_score, roc_auc_score, classification_report, precision_score, recall_score, f1_score
import numpy as np
from sklearn.model_selection import StratifiedKFold  # 导入分层KFold
import lightgbm as lgb  # 添加LightGBM导入
# 加载预处理后的数据
data_path = '/data/GuoCu_data/processed_data/toGBDT.csv'
df = pd.read_csv(data_path)

# 分离特征和标签
X = df.drop('label', axis=1)
y = df['label'].values  # 直接转换为NumPy数组

# 设置GBDT模型参数
params = {
    'objective': 'binary',
    'metric': 'auc',
    'boosting_type': 'gbdt',
    'num_leaves': 63,
    'max_depth': 6,
    'learning_rate': 0.001,
    'feature_fraction': 1,
    'bagging_fraction': 0.7,
    'bagging_freq': 5,
    'verbose': 0,
    'scale_pos_weight': 9.0,
    'boost_from_average': True,
    'lambda_l1': 0.01,
    'lambda_l2': 0.01,
    'min_data_in_leaf': 5,
    'min_sum_hessian_in_leaf': 1
}

# 决策阈值
threshold = 0.3

# 五折交叉验证
kfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
fold_aucs = []
fold_accuracies = []
fold_precisions = []
fold_recalls = []
fold_f1s = []

print("开始五折交叉验证...")

for fold, (train_idx, val_idx) in enumerate(kfold.split(X, y), 1):
    print(f"\n===== 第 {fold} 折 =====")
    
    # 划分训练集和验证集
    X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]
    y_train, y_val = y[train_idx], y[val_idx]
    
    # 创建 LightGBM 数据集
    lgb_train = lgb.Dataset(X_train, y_train)
    lgb_val = lgb.Dataset(X_val, y_val, reference=lgb_train)
    
    # 训练模型
    model = lgb.train(
        params,
        lgb_train,
        num_boost_round=1000,
        valid_sets=[lgb_train, lgb_val],
        callbacks=[
            lgb.early_stopping(stopping_rounds=50),
            lgb.log_evaluation(period=100)
        ]
    )
    
    # 在验证集上预测
    y_pred = model.predict(X_val, num_iteration=model.best_iteration)
    y_pred_binary = np.array([1 if x >= threshold else 0 for x in y_pred])
    
    # 评估当前折的模型
    auc = roc_auc_score(y_val, y_pred)
    accuracy = accuracy_score(y_val, y_pred_binary)
    precision = precision_score(y_val, y_pred_binary)
    recall = recall_score(y_val, y_pred_binary)
    f1 = f1_score(y_val, y_pred_binary)
    
    # 保存当前折的指标
    fold_aucs.append(auc)
    fold_accuracies.append(accuracy)
    fold_precisions.append(precision)
    fold_recalls.append(recall)
    fold_f1s.append(f1)
    
    print(f"第 {fold} 折验证结果:")
    print(f"AUC: {auc:.4f}")
    print(f"准确率: {accuracy:.4f}")
    print(f"精确率: {precision:.4f}")
    print(f"召回率: {recall:.4f}")
    print(f"F1 分数: {f1:.4f}")
    
# 计算五折平均指标
avg_auc = np.mean(fold_aucs)
avg_accuracy = np.mean(fold_accuracies)
avg_precision = np.mean(fold_precisions)
avg_recall = np.mean(fold_recalls)
avg_f1 = np.mean(fold_f1s)

print("\n===== 五折交叉验证平均结果 =====")
print(f"平均 AUC: {avg_auc:.4f}")
print(f"平均准确率: {avg_accuracy:.4f}")
print(f"平均精确率: {avg_precision:.4f}")
print(f"平均召回率: {avg_recall:.4f}")
print(f"平均 F1 分数: {avg_f1:.4f}")